﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AdminModule.IndexMarkServiceReference;
using AdminModule.Views;
using InpValidator;
using AdminModule.StructEditStratagies;
using AdminModule.CommonClasses;
using AdminModule.CustomXAMLElements;
using System.Collections.ObjectModel;
using AdminModule.ViewModels;

namespace AdminModule.UserControls.StructView
{
    public partial class IndexMarkStruct : StructViewBase
    {
        private IndexMarkServiceClient client = new IndexMarkServiceClient();

        private bool _WithCharacteristics = true;
        public bool WithCharacteristics
        {
            get
            {
                return this._WithCharacteristics;
            }
            set
            {
                this._WithCharacteristics = value;
            }
        }

        public IndexMarkStruct() : base()
        {
            InitializeComponent();
            this.viewModel = Resources["commonVM"] as CommonVM2;

            client.SaveIndexMarkStructCompleted += (s, ev) =>
                {
                    base.events.RaiseFreeEvent(FreeEvent.Save, s, ev);
                };
            client.CopyIndexMarkStructCompleted += (s, ev) =>
                {
                    base.events.RaiseFreeEvent(FreeEvent.Copy, s, ev);
                };
            client.CopyIndexMarkElementCompleted += (s, ev) =>
                {
                    base.events.RaiseFreeEvent(FreeEvent.Copy, s, ev);
                };
            client.GetIndexMarkStructOnDemandBySectionCompleted += (s, ev) =>
                {
                    (TreeView.SelectedItem as DTOChilds).Childs.LoadFrom(ev.Result);
                    base.events.RaiseFreeEvent(FreeEvent.LoadData, s, ev);
                };
            client.GetIndexMarkStructOnDemandByCharacteristicCompleted += (s, ev) =>
            {
                (TreeView.SelectedItem as DTOChilds).Childs.LoadFrom(ev.Result);
                base.events.RaiseFreeEvent(FreeEvent.LoadData, s, ev);
            };
        }

        public override void Init(int IDTerm)
        {
            base.Init(IDTerm);
            this.viewModel.Init(StructName.IndexMark, IDTerm);
            this.structEditStrategy = new IndexMarkStructEditStrategy2(IDTerm);
            this.SetBinding(this.viewModel, "IndexMarkStructRoots");
            this.SetTemplate(Resources["SectionRootLevel"] as DataTemplate);
        }

        public override void LoadData()
        {
            this.viewModel.LoadIndexMarkStruct(this.IDTerm, this.WithCharacteristics, base.isLoadOnDemand);
        }

        public override List<TypeInfo> GetTypesList()
        {
            List<TypeInfo> typesList = new List<TypeInfo>();
            typesList.Add(new TypeInfo
                {
                    Name = "Разделы",
                    window = new SelectAddItemsWindow(EnumSelectObjects.AdmSection),
                    forParentTypesAdd = new List<Type> { typeof(RootTreeView), typeof(AdmSection) },
                    forParentTypesReplace = new List<Type> { typeof(AdmSection) }
                });
            typesList.Add(new TypeInfo 
                { 
                    Name = "Показатели",
                    window = new SelectAddItemsWindow(EnumSelectObjects.AdmCharacteristic),
                    forParentTypesAdd = new List<Type> { typeof(AdmSection) },
                    forParentTypesReplace = new List<Type> { typeof(AdmCharacteristic) }
                });
            typesList.Add(new TypeInfo
            {
                Name = "Градации",
                window = new SelectAddItemsWindow(EnumSelectObjects.AdmGradationsStructSelectGroup, IDTerm, true, null, 1),
                forParentTypesAdd = new List<Type> { typeof(AdmCharacteristic) }
            });
            return typesList;
        }

        public override void Save()
        {
            base.events.RaiseBusyEvent(BusyEvent.Save);
            client.SaveIndexMarkStructAsync(StructViewBase.changedElements);
        }

        public override void CopyAll(int fromIDTerm, int toIDTerm)
        {
            base.events.RaiseBusyEvent(BusyEvent.Copy);
            client.CopyIndexMarkStructAsync(fromIDTerm, toIDTerm);
        }

        public override void CopySelected(DTOBase targetObject, int toIDTerm)
        {
            base.events.RaiseBusyEvent(BusyEvent.Copy);
            client.CopyIndexMarkElementAsync(CurrentItem.selectedItem, toIDTerm, 
                (targetObject is RootTreeView) ? null : targetObject);
        }

        public override void LoadOnDemand(TreeViewItem treeViewItem, DTOBase obj)
        {
            if (obj is AdmSection)
            {
                base.events.RaiseBusyEvent(BusyEvent.LoadData);
                client.GetIndexMarkStructOnDemandBySectionAsync(IDTerm, obj as AdmSection, WithCharacteristics);
            }
            if (obj is AdmCharacteristic)
            {
                base.events.RaiseBusyEvent(BusyEvent.LoadData);
                client.GetIndexMarkStructOnDemandByCharacteristicAsync(IDTerm, obj as AdmCharacteristic);
            }
        }

        /// <summary>
        /// Выбирает из списка категорий текущую категорию показателя
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void categoryComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            if (comboBox.SelectedItem != null) return;
            AdmCategory category = (comboBox.Tag as AdmCharacteristic).GetCategory();
            // Если это только что созданный объект, то у него отсутствует категория
            if (category == null) return;
            comboBox.SelectedItem = viewModel.Categories.First(f => f.IDCategory == category.IDCategory);
            // Задаем подсказку 
            ToolTipService.SetToolTip(comboBox, category.Name);
        }

        /// <summary>
        /// Если пользователь изменил категорию показателя, необходимо это зафиксировать
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void categoryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            AdmCategory category = comboBox.SelectedItem as AdmCategory;
            if (category == null) return;
            (comboBox.Tag as AdmCharacteristic).Category = category;
            // Задаем подсказку 
            ToolTipService.SetToolTip(comboBox, category.Name);
        }

        private void unitComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            if (comboBox.SelectedItem != null) return;
            AdmUnit unit = (comboBox.Tag as AdmCharacteristic).Unit;
            // Если это только что созданный объект, то у него отсутствует категория
            if (unit == null) return;
            comboBox.SelectedItem = viewModel.Units.First(f => f.IDUnit == unit.IDUnit);
        }

        private void unitComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            AdmUnit unit = comboBox.SelectedItem as AdmUnit;
            if (unit == null) return;
            (comboBox.Tag as AdmCharacteristic).Unit = unit;
        }

        private void rootNode_Loaded(object sender, RoutedEventArgs e)
        {
            this.TreeView.ExpandToDepth(1);
        }

        private void InitValidator(object sender, RoutedEventArgs e)
        {
            ValidatorBase v = sender as ValidatorBase;
            v.SetEnvironment(LayoutRoot, MainManager);
        }

        private void positionSelectHyperlink_Click2(object sender, RoutedEventArgs e)
        {
            SelectAddItemsWindow f = new SelectAddItemsWindow(EnumSelectObjects.AdmResponsible, IDTerm, true);
            AdmCharacteristic characteristic = base.CurrentItem.selectedItem as AdmCharacteristic;
            f.Closed += (s, ev) =>
            {
                if (f.DialogResult == false) return;

                characteristic.Responsibles.Clear();
                foreach (DTOBase i in f.GetObjects())
                {
                    Add(i);
                }
            };
            f.ShowForm(characteristic.Responsibles.Cast<DTOBase>(), true);
        }

        #region Проверка видимости полей Bottom и Top Limit
        private void gradationLimit_Loaded(object sender, RoutedEventArgs e)
        {
            TextBox txtBox = sender as TextBox;
            AdmGradation gradation = txtBox.Tag as AdmGradation;

            gradation.Childs.CollectionChanged += (s, ev) =>
                {
                    this.gradationLimit_CheckChilds(sender, e);
                };

            this.gradationLimit_CheckChilds(sender, e);
        }

        private void gradationLimit_CheckChilds(object sender, RoutedEventArgs e)
        {
            TextBox txtBox = sender as TextBox;
            AdmGradation gradation = txtBox.Tag as AdmGradation;
            txtBox.Visibility = (gradation.Childs.Count == 0 && gradation.Childs2.Count == 0) ? Visibility.Visible : Visibility.Collapsed;
        }

        private void characteristicLimit_Loaded(object sender, RoutedEventArgs e)
        {
            TextBox txtBox = sender as TextBox;
            AdmCharacteristic c = txtBox.Tag as AdmCharacteristic;

            c.Childs.CollectionChanged += (s, ev) =>
                {
                    this.characteristicLimit_CheckChilds(sender, e);
                };

            this.characteristicLimit_CheckChilds(sender, e);
        }

        private void characteristicLimit_CheckChilds(object sender, RoutedEventArgs e)
        {
            TextBox txtBox = sender as TextBox;
            AdmCharacteristic c = txtBox.Tag as AdmCharacteristic;
            txtBox.Visibility = (c.Childs.Count == 0 && c.Childs2.Count == 0) ? Visibility.Visible : Visibility.Collapsed;
        }
        #endregion

        /// <summary>
        /// Проверка видимости CheckBox IsNecessary для градации (отображается только в градациях верхнего уровня)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void IsNecessaryCheckBox_Loaded(object sender, RoutedEventArgs e)
        {
            CheckBox checkBox = sender as CheckBox;
            AdmGradation gradation = checkBox.Tag as AdmGradation;

            if (gradation.IDParentGradationTerm == null)
                checkBox.Visibility = System.Windows.Visibility.Visible;
            else
                checkBox.Visibility = System.Windows.Visibility.Collapsed;
        }

        /// <summary>
        /// Проверка видимости веса (отсутствует у градаций верхнего уровня)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gradationWeightStackPanel_Loaded(object sender, RoutedEventArgs e)
        {
            StackPanel stackPanel = sender as StackPanel;
            AdmGradation gradation = stackPanel.Tag as AdmGradation;
        }

    }
}
